package client

import (
	. "chess_platform/internal/common"
	"chess_platform/models/client"
	"chess_platform/models/h5"
	"chess_platform/models/pc"
	"fmt"
	"github.com/astaxie/beego/orm"
	"strconv"
	"time"
)

//[client]亲友圈
type ClubController struct {
	GrantController
}

func (b *ClubController) URLMapping() {
	b.Mapping("TestNewClub", b.TestNewClub)
	b.Mapping("NewClub", b.NewClub)
	b.Mapping("UpdatePartOneClub", b.UpdatePartOneClub)
	b.Mapping("UpdatePartTwoClub", b.UpdatePartTwoClub)
	b.Mapping("ImportMember", b.ImportMember)
	b.Mapping("ChangeClubStatus", b.ChangeClubStatus)
	b.Mapping("ClubInfo", b.ClubInfo)
	b.Mapping("ListClub", b.ListClub)
	b.Mapping("ExitClub", b.ExitClub)
	b.Mapping("JoinClub", b.JoinClub)
	b.Mapping("ChangeMemberStatus", b.ChangeMemberStatus)
	b.Mapping("ChangeMemberRole", b.ChangeMemberRole)
	b.Mapping("ListMember", b.ListMember)
	b.Mapping("ListClubOnlineMember", b.ListClubOnlineMember)

	//-----------俱乐部楼层---第二版的接口-----------------//
	b.Mapping("NewFloor", b.NewFloor)
	b.Mapping("UpdateFloor", b.UpdateFloor)
	b.Mapping("UpdateFloorName", b.UpdateFloorName)
	b.Mapping("UpdateFloorNotice", b.UpdateFloorNotice)
	b.Mapping("ListFloor", b.ListFloor)
	b.Mapping("DeleteFloor", b.DeleteFloor)
	b.Mapping("PassiveJoinClub", b.PassiveJoinClub)
	b.Mapping("ChangeClubHost", b.ChangeClubHost)

}

// @Title 测试是否满足条件(钻石数,亲友圈个数)创建亲友圈
// @Description 测试是否满足条件(钻石数,亲友圈个数)创建亲友圈
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /test-new-club [post]
func (b *ClubController) TestNewClub() {
	var defaultClubDiamond int64
	r1, err := h5.RuleByType(RulePlayerClubDiamond)
	if err == nil {
		defaultClubDiamond = r1.Amount
	} else { //说明没有设置,就能一个默认值,保证程序能正常运行
		defaultClubDiamond = 300
	}
	diamond := client.UserDiamondById(b.Uid)
	if diamond < defaultClubDiamond {
		b.ResponseFail(fmt.Sprintf("您必须拥有%v钻石才能创建VIP亲友圈", defaultClubDiamond))
		return
	}

	//统计此用户已经有多少个亲友圈
	clubNum := client.StatPlayerClubNum(b.Uid)
	//获取每个用户默认开亲友圈个数的限制
	var defaultClubNum int64
	r, err := h5.RuleByType(RulePlayerClubNum)
	if err == nil {
		defaultClubNum = r.Amount
	} else { //说明没有设置,就能一个默认值,保证程序能正常运行
		defaultClubNum = 20
	}

	if clubNum >= defaultClubNum {
		b.ResponseFail("亲友圈数量已达上限")
		return
	}
	b.ResponseSuccess()
}

// @Title 创建亲友圈
// @Description 创建亲友圈
// @Param   name  	 body    string  true      "亲友圈名字(2-7个字符)"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /new-club [post]
func (b *ClubController) NewClub() {
	var defaultClubDiamond int64
	r1, err := h5.RuleByType(RulePlayerClubDiamond)
	if err == nil {
		defaultClubDiamond = r1.Amount
	} else { //说明没有设置,就能一个默认值,保证程序能正常运行
		LogClient.Warning("没有设置创建俱乐部至少需要钻石数,使用默认的300")
		defaultClubDiamond = 300
	}
	diamond := client.UserDiamondById(b.Uid)
	if diamond < defaultClubDiamond {
		b.ResponseFail(fmt.Sprintf("您必须拥有%v钻石才能创建VIP亲友圈", defaultClubDiamond))
		return
	}

	//统计此用户已经有多少个亲友圈
	clubNum := client.StatPlayerClubNum(b.Uid)
	//获取每个用户默认开亲友圈个数的限制
	var defaultClubNum int64
	r, err := h5.RuleByType(RulePlayerClubNum)
	if err == nil {
		defaultClubNum = r.Amount
	} else { //说明没有设置,就能一个默认值,保证程序能正常运行
		LogClient.Warning("没有设置最多能创建多少个俱乐部,使用默认的20")
		defaultClubNum = 20
	}

	if clubNum >= defaultClubNum {
		b.ResponseFail("亲友圈数量已达上限")
		return
	}

	type Params struct {
		Name string `json:"name"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	b.Valid.Required(p.Name, "name").Message("亲友圈名称不能为空")
	b.Valid.MaxSize(p.Name, 7, "name").Message("最多为7个字符")
	b.Valid.MinSize(p.Name, 2, "name").Message("最少为2个字符")
	if !b.VerifyParamsError() {
		return
	}

	o := NewDBOrm(DBChess)
	o.Begin()
	defer o.Rollback()

	//获取默认的亲友圈开桌数
	var tableNum int64
	rule, err := h5.RuleByType(RuleClubTableNum)
	if err == nil {
		tableNum = rule.Amount
	} else { //说明没有设置
		LogClient.Warning("没有设置最多能创建多少个桌子数,使用默认的20")
		tableNum = 20 //随便一个值,保证可用
	}

	//获取默认的亲友圈创建楼层数
	var floorNum int64
	ruleFloor, err := h5.RuleByType(RuleClubFloorNum)
	if err == nil {
		floorNum = ruleFloor.Amount
	} else { //说明没有设置
		LogClient.Warning("没有设置最多能创建多少层,使用默认的5")
		floorNum = 5 //随便一个值,保证可用
	}

	password := client.GetNormalClubNumber(o)
	if password == 0 {
		o.Rollback()
		b.ResponseFail("创建失败")
		return
	}

	club := map[string]interface{}{
		"password":    password,
		"name":        p.Name,
		"host_id":     b.Uid,
		"is_audit":    1, //默认需要审核
		"member":      1, //初始时成员就只有自己,所以为1
		"table_num":   tableNum,
		"floor_num":   floorNum,
		"create_time": time.Now().Unix(),
		//"modify_time": time.Now().Unix(), 刚创建的亲友圈,当天能再修改一次,所以要注释此代码
	}
	id, _ := pc.WhiteUserById(b.Uid)
	if id == b.Uid { //此用户具有上下分功能
		club["is_contest"] = 1
	}

	cid, err := client.NewClub(club, o)
	if err != nil {
		o.Rollback()
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}

	//创建亲友圈时要把自己加入到亲友圈成员里去，并把自己设置为创建人
	cm := map[string]interface{}{
		"uid":         b.Uid,
		"cid":         cid,
		"role":        ClubRoleOwner,
		"status":      ClubMemberNormal,
		"create_time": time.Now().Unix(),
	}
	_, err = client.NewClubMember(cm, o)
	if err != nil {
		o.Rollback()
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	o.Commit()
	b.Res.Data = map[string]interface{}{
		"club_id":  cid,
		"password": password,
	}
	b.ResponseSuccess()

	Key := fmt.Sprintf("%v%v", KeyClub, cid)
	Redis.HSet(Key, "host", b.Uid)
	Redis.HSet(Key, b.Uid, b.Uid)
	Redis.HSet(Key, "password", password)

	//初始化的游戏game_type,play_type
	Redis.HSet(Key, "game_type", 0)
	Redis.HSet(Key, "play_type", 0)

	//开房桌子数
	Redis.HSet(Key, "table_num", tableNum)
}

// @Title 更新亲友圈(游戏ID,游戏规则，游戏选项)
// @Description 更新亲友圈(游戏ID,游戏规则，游戏选项)
// @Param   id        	body    int     true      "id"
// @Param   game_id   	body    int     true      "游戏id"
// @Param   play_rule 	body    string  true      "游戏玩法规则"
// @Param   play_option body    int     true      "游戏玩法选项"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /update-part-two-club [post]
func (b *ClubController) UpdatePartTwoClub() {
	type Params struct {
		Id         int64  `json:"id" valid:"Required"`
		GameId     int64  `json:"game_id"`
		PlayRule   string `json:"play_rule"`
		PlayOption int64  `json:"play_option"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	status, role, ok := client.IsClubMemberExist(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是此亲友圈成员,无权操作"
		b.Response()
		return
	}
	if status != ClubMemberNormal {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您已被拉黑,无权操作"
		b.Response()
		return
	}
	if role != ClubRoleOwner && role != ClubRoleAdmin {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是创建人或管理员,无权操作"
		b.Response()
		return
	}

	data := map[string]interface{}{
		"game_id":     p.GameId,
		"play_rule":   p.PlayRule,
		"play_option": p.PlayOption,
	}
	_, err := client.UpdateClub(data, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	gameType, playType := AnalysisGameId(p.GameId)
	Key := fmt.Sprintf("%v%v", KeyClub, p.Id)
	Redis.HSet(Key, "game_type", gameType)
	Redis.HSet(Key, "play_type", playType)
	b.ResponseSuccess()
	//亲友圈更新了要发送亲友圈所有成员
	client.BroadCastMsgToLobby(p.Id, GenBroadcastMsg(ModuleClub, ActionUpdateClub, p.Id))
}

// @Title 导入其它亲友圈的成员
// @Description 导入其它亲友圈的成员
// @Param   from_id        	body    int     true      "传数组形式[id1,id2,id3]俱乐部id,不是俱乐部密码(从此俱乐部导入到to_id俱乐部)"
// @Param   to_id        	body    int     true      "俱乐部id,不是俱乐部密码"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /import-member [post]
func (b *ClubController) ImportMember() {
	type Params struct {
		FromId []int64 `json:"from_id" valid:"Required"`
		ToId   int64   `json:"to_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	if len(p.FromId) < 1 {
		b.ResponseFail("请至少选择一个亲友圈")
		return
	}

	//获取亲友圈人数限制
	rule, err := h5.RuleByType(RuleClubMemberNum)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if rule.Id == 0 {
		rule.Amount = 500 //给一个限制，保证程序可运行
		LogClient.Error("亲友圈成员数限制未设置,请限制")
	}

	o := NewDBOrm(DBChess)
	uid, err := client.ListImportMember(p.FromId, o)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	Key := fmt.Sprintf("%v%v", KeyClub, p.ToId)
	var isBeyondMember bool
	for k, v := range uid {
		if int64(k) > rule.Amount { //超过人数限制
			isBeyondMember = true
			break
		}
		data := map[string]interface{}{
			"uid":         v,
			"cid":         p.ToId,
			"role":        ClubRoleNormal,
			"status":      ClubMemberNormal,
			"create_time": time.Now().Unix(),
		}
		_, err := client.NewClubMember(data, o)
		if err != nil {
			LogClient.Error(fmt.Sprintf("导入亲友圈成员出错:%v", err))
		} else {
			Redis.HSet(Key, v, v)
			u, _ := client.QueryUserInfoById(b.Uid)
			data := map[string]interface{}{
				"type":      EmailTypePay,
				"suid":      0,
				"ruid":      v,
				"nickname":  "系统消息",
				"title":     "邀请加入亲友圈通知",
				"content":   fmt.Sprintf("玩家(ID:%v,昵称:%v)已邀请您加入VIP亲友圈(ID:%v)", b.Uid, u.Nickname, p.ToId),
				"status":    0,
				"send_time": time.Now().Unix(),
			}
			client.SendEmailAndNotifyClient(data, v, 0, "")
		}
	}
	//更新亲友圈成员总数
	client.UpdateClubMemberNum(p.ToId)
	if isBeyondMember {
		b.ResponseSuccess("导入完成,因为总人数超过上限,部分成员没有导入")
		return
	}
	b.ResponseSuccess("导入完成")
}

// @Title 更新亲友圈(亲友圈名字,审核,战绩公开)
// @Description 更新亲友圈(亲友圈名字,审核,战绩公开)
// @Param   id        	body    int     true      "id"
// @Param   name      	body    string  true      "亲友圈名称"
// @Param   is_audit  	body    int     true      "是否需要审核加入，1-是，0-否"
// @Param   is_open   	body    int     true      "是否公布战绩，1-是，0-否"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /update-part-one-club [post]
func (b *ClubController) UpdatePartOneClub() {
	type Params struct {
		Id      int64  `json:"id" valid:"Required"`
		Name    string `json:"name"`
		IsAudit int64  `json:"is_audit" valid:"Range(0,1)"`
		IsOpen  int64  `json:"is_open" valid:"Range(0,1)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	b.Valid.Required(p.Name, "name").Message("亲友圈名称不能为空")
	b.Valid.MaxSize(p.Name, 7, "name").Message("最多为7个字符")
	b.Valid.MinSize(p.Name, 2, "name").Message("最少为2个字符")
	if !b.ValidParams(&p) {
		return
	}

	status, role, ok := client.IsClubMemberExist(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是此亲友圈成员,无权操作"
		b.Response()
		return
	}
	if status != ClubMemberNormal {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您已被拉黑,无权操作"
		b.Response()
		return
	}
	if role != ClubRoleOwner && role != ClubRoleAdmin {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是创建人或管理员,无权操作"
		b.Response()
		return
	}

	club, err := client.ClubStructById(p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if club.Id == 0 || club.Status == ClubDismiss { //不存在
		b.Res.Code = ErrNotFound
		b.Res.Msg = "亲友圈不存在"
		b.Response()
		return
	}

	if p.Name != club.Name && IsToday(club.ModifyTime) {
		b.ResponseFail("亲友圈名称每天只能修改一次")
		return
	}

	data := map[string]interface{}{
		"name":     p.Name,
		"is_audit": p.IsAudit,
		"is_open":  p.IsOpen,
	}
	if p.Name != club.Name { //说明修改了亲友圈名称
		data["modify_time"] = time.Now().Unix()
	}

	_, err = client.UpdateClub(data, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	//亲友圈更新了要发送亲友圈所有成员
	client.BroadCastMsgToLobby(p.Id, GenBroadcastMsg(ModuleClub, ActionUpdateClub, p.Id))
}

// @Title 改变亲友圈状态(正常,解散,冻结)
// @Description 改变亲友圈状态(正常,解散,冻结)
// @Param   id           body   int        true        "id"
// @Param   status       body   int        true        "1-正常，2-解散,3-冻结"
// @Success 0 {string}  状态码
// @router /change-club-status [post]
func (b *ClubController) ChangeClubStatus() {
	type Params struct {
		Id     int64 `json:"id" valid:"Required"`
		Status int64 `json:"status" valid:"Range(1,3)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	status, role, ok := client.IsClubMemberExist(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是此亲友圈成员,无权操作"
		b.Response()
		return
	}
	if status != ClubMemberNormal {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您已被拉黑,无权操作"
		b.Response()
		return
	}
	if p.Status == ClubDismiss && role != ClubRoleOwner {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是创建人,无权操作"
		b.Response()
		return
		//只有管理员或创建人才有权恢复或冻结亲友圈
	} else if (p.Status == ClubNormal || p.Status == ClubFrozen) && (role != ClubRoleOwner && role != ClubRoleAdmin) {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是管理员或创建人,无权操作"
		b.Response()
		return
	}

	club := map[string]interface{}{
		"status": p.Status,
	}

	o := NewDBOrm(DBChess)
	_, err := client.UpdateClub(club, p.Id, o)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}

	Key := fmt.Sprintf("%v%v", KeyClub, p.Id)
	password, _ := Redis.HGet(Key, "password")
	u, _ := client.QueryUserInfoById(b.Uid)
	switch p.Status {
	//前端数据传来不会正常的时候再把亲友圈更新为正常
	case ClubNormal:
		content := fmt.Sprintf("创建人或管理员(ID:%v,昵称:%v)恢复了亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		client.SendEmailToClubMember(content, "恢复亲友圈", ActionResumeClub, p.Id, o)
	case ClubDismiss:
		//解散了亲友圈要把缓存删掉，这样游戏客户端那里玩家就进不了亲友圈了
		Key := fmt.Sprintf("%v%v", KeyClub, p.Id)
		Redis.Del(Key)
		content := fmt.Sprintf("创建人(ID:%v,昵称:%v)解散了亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		client.SendEmailToClubMember(content, "解散亲友圈", ActionDismissClub, p.Id, o)
		client.RecycleClubNumber(password, o)
	case ClubFrozen:
		content := fmt.Sprintf("创建人或管理员(ID:%v,昵称:%v)冻结了亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		client.SendEmailToClubMember(content, "冻结亲友圈", ActionFrozenClub, p.Id, o)
	}
	b.ResponseSuccess()
}

// @Title 亲友圈信息(有变动,会返回亲友圈密码)
// @Description 亲友圈信息(有变动,会返回亲友圈密码)
// @Param   id           body   int        true        "id"
// @Success 0 {string}  状态码
// @router /club-info [post]
func (b *ClubController) ClubInfo() {
	type Params struct {
		Id int64 `json:"id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	club, err := client.ClubMapById(b.Uid, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	client.StatClubMemberOnline(club)
	b.Res.Data = club
	b.ResponseSuccess()
}

// @Title 玩家参与的亲友圈列表(有变动,显示password)
// @Description 玩家参与的亲友圈列表(有变动,显示password)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Success 0 {object} []common.Club 亲友圈列表
// @router /list-club [post]
func (b *ClubController) ListClub() {
	var p ListParams
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	//要做缓存的，现在先不做
	////非频繁变动的数据不进行缓存
	//Key := fmt.Sprintf("%v%v-%v-%v", KeyListClub, b.Uid, p.PageIndex, p.PageSize)
	//club, err := GetSliceCache(Key)
	//if err != nil {
	//	LogClient.Error(fmt.Sprintf("获取亲友圈列表(key:%v)redis里缓存失败:%v", Key, err))
	//}
	//var count int64
	//count, _ = Redis.GetInt64(KeyListClubCount)
	//if club == nil { //cache doesn't exist
	club, count, err := client.ListClub(p, b.Uid)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//SetSliceCache(Key, club, ClientCacheExpire)
	//Redis.Set(KeyListClubCount, "EX", count, ClientCacheExpire)
	//	}

	//频繁变动的数据不进行缓存
	client.StatClubMemberOnline(club...)
	b.Res.Data = club
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 主动退出亲友圈(同时通知创建人及管理员)
// @Description  主动退出亲友圈(同时通知创建人及管理员)
// @Param   club_id           body   int        true        "id"
// @Success 0 {string}  状态码
// @router /exit-club [post]
func (b *ClubController) ExitClub() {
	type Params struct {
		ClubId int64 `json:"club_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	//退出亲友圈成员，只是把成员状态改为delete
	cm := map[string]interface{}{
		"status": ClubMemberDelete,
		"role":   ClubRoleNormal,
	}
	//主动退出的成员，只是改了状态,下次重新加入时，会把状态改为未审核,其它归为默认值
	_, err := client.UpdateClubMemberById(cm, b.Uid, p.ClubId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}

	//更新亲友圈成员总数
	client.UpdateClubMemberNum(p.ClubId)
	//把亲友圈成员从redis踢除
	Key := fmt.Sprintf("%v%v", KeyClub, p.ClubId)
	Redis.HDel(Key, b.Uid, b.Uid)
	password, _ := Redis.HGet(Key, "password")

	b.ResponseSuccess()
	t := time.Now()
	u, _ := client.QueryUserInfoById(b.Uid)
	//发邮件通知创建人及管理员(同时实时通知)
	data := map[string]interface{}{
		"type":      EmailTypeSys,
		"suid":      0,
		"nickname":  "系统消息",
		"title":     "亲友圈通知",
		"content":   fmt.Sprintf("亲友圈成员(ID:%v,昵称:%v)在%v主动退出了亲友圈(ID:%v)", b.Uid, u.Nickname, t.Format("2006-01-02 15:04"), password),
		"status":    0,
		"send_time": t.Unix(),
	}
	userId := client.ListClubHostAndAdmin(p.ClubId)
	for _, uid := range userId {
		data["ruid"] = uid
		client.SendEmailAndNotifyClient(data, uid, 0, GenBroadcastMsg(ModuleClub, ActionExitClub, p.ClubId))
	}

}

// @Title 申请加入亲友圈(有变动,亲友圈密码)
// @Description 申请加入亲友圈(有变动,亲友圈密码)
// @Param   password          body   int        true        "亲友圈ID(亲友圈密码)"
// @Success 0 {string}  状态码
// @router /join-club [post]
func (b *ClubController) JoinClub() {
	type Params struct {
		Password int64 `json:"password" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if p.Password == 0 {
		b.ResponseFail("亲友圈不存在")
		return
	}
	//判断下此亲友圈是否需要审核之后才能加入
	club, err := client.ClubStructByPassword(p.Password)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if club.Id == 0 { //不存在
		b.Res.Code = ErrNotFound
		b.Res.Msg = "亲友圈不存在"
		b.Response()
		return
	}
	//查找是否已经是此亲友圈成员(正常或禁言)，如果是无需重复加入
	status, _, ok := client.IsClubMemberExist(club.Id, b.Uid)
	if ok {
		if status == ClubMemberNormal || status == ClubMemberMute {
			b.Res.Msg = "您已是此亲友圈成员,无需重复加入"
			b.Res.Code = ErrAlreadyExist
			b.Response()
			return
		} else if status == ClubMemberAudit {
			b.Res.Msg = "您已申请加入,请耐心等待审核"
			b.Res.Code = ErrAlreadyExist
			b.Response()
			return
		}
	}
	//获取亲友圈人数限制
	rule, err := h5.RuleByType(RuleClubMemberNum)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if rule.Id != 0 {
		if rule.Amount <= club.Member {
			b.ResponseFail("加入失败,亲友圈成员已达上限")
			return
		}
	} else {
		LogClient.Error("亲友圈成员数限制未设置,请限制")
	}
	cm := map[string]interface{}{
		"uid":         b.Uid,
		"cid":         club.Id,
		"role":        ClubRoleNormal,
		"status":      ClubMemberAudit,
		"create_time": time.Now().Unix(),
	}

	msg := GenBroadcastMsg(ModuleClub, ActionJoinClub, club.Id)
	if club.IsAudit == 0 { //不需要审核
		cm["status"] = ClubMemberNormal
		_, err = client.NewClubMember(cm)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}

		//更新亲友圈成员总数
		client.UpdateClubMemberNum(club.Id)
		//添加亲友圈成员到redis里,
		Key := fmt.Sprintf("%v%v", KeyClub, club.Id)
		Redis.HSet(Key, b.Uid, b.Uid)

		//通知申请者
		msg = GenBroadcastMsg(ModuleClub, ActionJoinClubSuccess, club.Id)
		client.BroadCastMsgToLobby(0, msg, b.Uid) //发送消息给申请者，提示它你已成功加入

		//实时通知创建人及管理员有新成员申请加入,好让他们及时审核,不用发邮件
		client.NotifyClubHostAndAdmin(club.Id, msg)
		b.ResponseSuccessTwo("加入成功,你已是亲友圈成员")
	} else { //需要审核
		//如果曾经加入过，再次加入时会直接把状态改为未审核,并且把之前的数据都归为默认的
		_, err = client.NewClubMember(cm)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		//实时通知创建人及管理员有新成员申请加入,好让他们及时审核,不用发邮件
		client.NotifyClubHostAndAdmin(club.Id, msg)
		b.ResponseSuccess("加入成功,请等待审核")
	}

}

// @Title 改变亲友圈成员状态(拒绝,正常,禁言)
// @Description 改变亲友圈成员状态(拒绝,正常,禁言)
// @Param   player_id    body   int        true        "亲友圈成员id"
// @Param   club_id      body   int        true        "id"
// @Param   status       body   int        true        "状态, 2-拒绝,3-正常(审核通过),4-禁言(被拉黑),5-被删除"
// @Success 0 {string}  状态码
// @router /change-member-status [post]
func (b *ClubController) ChangeMemberStatus() {
	type Params struct {
		PlayerId int64 `json:"player_id" valid:"Required"`
		ClubId   int64 `json:"club_id" valid:"Required"`
		Status   int64 `json:"status" valid:"Range(2,5)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	if b.Uid == p.PlayerId {
		b.ResponseFail("不能自己操作自己")
		return
	}

	//只有创建人或管理员(正常的管理员,被禁言的无权限)才能审核
	status, role, ok := client.IsClubMemberExist(p.ClubId, b.Uid)
	if !ok || (ok && role != ClubRoleOwner && role != ClubRoleAdmin && status != ClubMemberNormal) {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是此亲友圈管理员或创建人,无权操作"
		b.Response()
		return
	}
	//管理员不能操作管理员,只有创建人才可以
	playerStatus, playerRole, ok := client.IsClubMemberExist(p.ClubId, p.PlayerId)
	if !ok || playerStatus == ClubMemberDelete {
		b.Res.Code = ErrNotFound
		b.Res.Msg = "此成员已被其它管理员或创建人删除"
		b.Response()
		return
	}
	//管理员之前不能相互操作,只有创建人才可以
	if playerRole == ClubRoleAdmin && role != ClubRoleOwner {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "管理员不能操作管理员"
		b.Response()
		return
	}

	//发邮件通知玩家
	data := map[string]interface{}{
		"type":      EmailTypeSys,
		"suid":      0,
		"ruid":      p.PlayerId,
		"nickname":  "系统消息",
		"title":     "亲友圈通知",
		"status":    0,
		"send_time": time.Now().Unix(),
	}
	cm := map[string]interface{}{
		"status": p.Status,
	}
	Key := fmt.Sprintf("%v%v", KeyClub, p.ClubId)
	password, _ := Redis.HGet(Key, "password")

	u, _ := client.QueryUserInfoById(b.Uid)
	switch p.Status {
	case ClubMemberNormal: //同意加入,或取消拉黑
		//要区分同意加入还是取消拉黑
		action := ActionAgreeClubMemberJoin
		if playerStatus == ClubMemberAudit { //同意加入
			club, err := client.ClubStructById(p.ClubId)
			if err != nil {
				LogClient.Error(b.DatabaseError(err.Error()))
				return
			}
			if club.Id == 0 || club.Status == ClubDismiss { //不存在
				b.Res.Code = ErrNotFound
				b.Res.Msg = "亲友圈不存在"
				b.Response()
				return
			}
			//获取亲友圈人数限制
			rule, err := h5.RuleByType(RuleClubMemberNum)
			if err != nil {
				LogClient.Error(b.DatabaseError(err.Error()))
				return
			}
			if rule.Id != 0 {
				if rule.Amount <= club.Member {
					b.ResponseFail("加入失败,亲友圈成员已达上限")
					return
				}
			} else {
				LogClient.Error("亲友圈成员数限制未设置,请限制")
			}

			data["content"] = fmt.Sprintf("亲友圈创建人或管理员(ID:%v,昵称:%v)同意了您的申请,欢迎加入亲友圈(ID:%v)", b.Uid, u.Nickname, password)

			_, err = client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
			if err != nil {
				LogClient.Error(b.DatabaseError(err.Error()))
				return
			}
			//更新亲友圈成员总数
			client.UpdateClubMemberNum(p.ClubId)
			//添加亲友圈成员到redis里,
			Key := fmt.Sprintf("%v%v", KeyClub, p.ClubId)
			Redis.HSet(Key, p.PlayerId, p.PlayerId)
			err = client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, action, p.ClubId))
			if err != nil {
				LogClient.Error(fmt.Sprintf("审核成员加入时出错了:%v", err))
				b.ResponseFail("审核失败")
				return
			}

			b.ResponseSuccess()
			return

		} else if playerStatus == ClubMemberMute { //取消拉黑
			data["content"] = fmt.Sprintf("亲友圈创建人或管理员(ID:%v,昵称:%v)取消了拉黑,欢迎您回归亲友圈(ID:%v)", b.Uid, u.Nickname, password)
			action = ActionCancelClubMemberBlock
			_, err := client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
			if err != nil {
				LogClient.Error(b.DatabaseError(err.Error()))
				return
			}
			client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, action, p.ClubId))
			b.ResponseSuccess()
			return
		}
	case ClubMemberReject: //不同意加入(拒绝)
		//被拒绝的成员，只是改了状态,下次重新加入时，会把状态改为未审核
		_, err := client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		b.ResponseSuccess()

		data["content"] = fmt.Sprintf("亲友圈创建人或管理员(ID:%v,昵称:%v)拒绝了您的申请加入亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, ActionRejectClubMember, p.ClubId))
		return
	case ClubMemberMute: //拉黑(禁言)
		//把此成员拉黑之后要把他的角色变成普通成员
		cm["role"] = ClubRoleNormal

		_, err := client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		//更新亲友圈成员总数,没必要重新统计,因为拉黑的也算亲友圈成员之一
		//client.UpdateClubMemberNum(p.ClubId)
		b.ResponseSuccess()

		data["content"] = fmt.Sprintf("亲友圈创建人或管理员(ID:%v,昵称:%v)把您拉黑了,亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, ActionBlockClubMember, p.ClubId))
		return
	case ClubMemberDelete: //踢出
		//把此成员删除之后要把他的角色变成普通成员
		cm["role"] = ClubRoleNormal
		//被拒绝的成员，只是改了状态,下次重新加入时，会把状态改为未审核
		_, err := client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		//更新亲友圈成员总数
		client.UpdateClubMemberNum(p.ClubId)
		b.ResponseSuccess()

		//从redis里删除亲友圈成员
		Key := fmt.Sprintf("%v%v", KeyClub, p.ClubId)
		Redis.HDel(Key, p.PlayerId, p.PlayerId)
		data["content"] = fmt.Sprintf("亲友圈创建人或管理员(ID:%v,昵称:%v)把您踢出亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, ActionDeleteClubMember, p.ClubId))
		return
	}

}

// @Title 改变亲友圈成员角色(普通成员,管理员)
// @Description 改变亲友圈成员角色(普通成员,管理员)
// @Param   player_id    body   int        true        "亲友圈成员id"
// @Param   club_id      body   int        true        "id"
// @Param   role         body   int        true        "成员角色,1-普通成员，2-管理员"
// @Success 0 {string}  状态码
// @router /change-member-role [post]
func (b *ClubController) ChangeMemberRole() {
	type Params struct {
		PlayerId int64 `json:"player_id" valid:"Required"`
		ClubId   int64 `json:"club_id" valid:"Required"`
		Role     int64 `json:"role" valid:"Range(1,2)"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	//只有创建人才能改变成员角色
	/*
		1. 创建人可以改变所有人的角色(除了自己)
		2. 管理员或普通成员都不能改变别人的角色
	*/
	if b.Uid == p.PlayerId {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "不能改变自己的角色"
		b.Response()
		return
	}
	_, role, ok := client.IsClubMemberExist(p.ClubId, b.Uid)
	if !ok || (ok && role != ClubRoleOwner) {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是此亲友圈创建人,无权操作"
		b.Response()
		return
	}

	cm := map[string]interface{}{
		"role": p.Role,
	}

	//发邮件通知玩家(同时实时通知)
	data := map[string]interface{}{
		"type":      EmailTypeSys,
		"suid":      0,
		"ruid":      p.PlayerId,
		"nickname":  "系统消息",
		"title":     "亲友圈通知",
		"status":    0,
		"send_time": time.Now().Unix(),
	}

	Key := fmt.Sprintf("%v%v", KeyClub, p.ClubId)
	password, _ := Redis.HGet(Key, "password")
	u, _ := client.QueryUserInfoById(b.Uid)
	switch p.Role {
	case ClubRoleAdmin:
		if client.CountClubAdmin(p.ClubId) >= 10 { //亲友圈管理员不能超过2个
			b.ResponseFail("管理人数已达上限")
			return
		}
		//如果设置为管理员，则要把成员的状态改为正常(不管是它之前是否被拉黑之类的)
		cm["status"] = ClubMemberNormal
		data["content"] = fmt.Sprintf("亲友圈创建人(ID:%v,昵称:%v)把您升级成管理员,亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		_, err := client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, ActionUpgradeClubMember, p.ClubId))
	case ClubRoleNormal:
		data["content"] = fmt.Sprintf("亲友圈创建人(ID:%v,昵称:%v)把您降级成普通成员,亲友圈(ID:%v)", b.Uid, u.Nickname, password)
		_, err := client.UpdateClubMemberById(cm, p.PlayerId, p.ClubId)
		if err != nil {
			LogClient.Error(b.DatabaseError(err.Error()))
			return
		}
		client.SendEmailAndNotifyClient(data, p.PlayerId, 0, GenBroadcastMsg(ModuleClub, ActionDowngradeClubMember, p.ClubId))
	}

	b.ResponseSuccess()
}

// @Title 亲友圈成员列表(有变动,type=3时，要显示亲友圈密码)
// @Description 亲友圈成员列表(有变动,type=3时，要显示亲友圈密码)
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   club_id      body   int     false      "亲友圈id"
// @Param   type         body   int     true       "1-正常及禁言的成员列表,2-待审核的成员列表,3-所有亲友圈待审核的成员列表"
// @Param   search       body   int     false      "玩家ID或玩家名字(非必传)"
// @Success 0 {object} []common.ClubMember 亲友圈成员列表
// @router /list-member [post]
func (b *ClubController) ListMember() {
	type Params struct {
		ListParams
		ClubId int64  `json:"club_id"`
		Type   int64  `json:"type" valid:"Range(1,3)"`
		Search string `json:"search"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	var (
		clubMember []orm.Params
		count      int64
		err        error
	)
	//要做缓存,现在先不做
	if p.Type == 1 {
		//可能做不了缓存，因为离线时间要排序,不做缓存的话要去掉clubMemberOnlineStatus函数，没必要了
		var uid int64
		var name string
		if IsNumber(p.Search) {
			uid, _ = strconv.ParseInt(p.Search, 10, 64)
		} else {
			name = p.Search
		}
		clubMember, count, err = client.ListClubMember(p.ListParams, p.ClubId, uid, name)
		client.ClubMemberOnlineStatus(clubMember)
	} else if p.Type == 2 {
		clubMember, count, err = client.ListAuditClubMember(p.ListParams, p.ClubId)
	} else {
		clubMember, count, err = client.ListAllAuditClubMember(p.ListParams, b.Uid)
	}
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = clubMember
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 亲友圈在线成员列表
// @Description 亲友圈在线成员列表
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   club_id      body   int     false      "亲友圈id"
// @Success 0 {object} []common.ClubMember 亲友圈成员列表
// @router /list-club-online-member [post]
func (b *ClubController) ListClubOnlineMember() {
	type Params struct {
		ListParams
		ClubId int64 `json:"club_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	clubMember, count, err := client.ListClubOnlineMember(p.ListParams, p.ClubId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}

	b.Res.Data = clubMember
	b.Res.Count = count
	b.ResponseSuccess()
}

//-------------------------------俱乐部改成楼层模式-----------------------------//

// @Title 创建楼层
// @Description 创建楼层
// @Param   club_id  	 body    int     true      "俱乐部id,不是密码"
// @Param   game_id  	 body    int     true      "游戏id"
// @Param   play_rule 	 body    string  true      "游戏玩法规则"
// @Param   play_option  body    int     true      "游戏玩法选项"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /new-floor [post]
func (b *ClubController) NewFloor() {
	type Params struct {
		ClubId     int64  `json:"club_id" valid:"Required"`
		GameId     int64  `json:"game_id"`
		PlayRule   string `json:"play_rule"`
		PlayOption int64  `json:"play_option"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	count, err := client.CountFloor(p.ClubId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//获取默认的亲友圈创建楼层数
	ruleFloor, err := h5.RuleByType(RuleClubFloorNum)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if ruleFloor.Amount <= count {
		LogClient.Info(fmt.Sprintf("俱乐部id:%v,已有楼层数:%v,限制楼层数:%v", p.ClubId, count, ruleFloor.Amount))
		b.ResponseFail("楼层数量已达上限")
		return
	}

	_, role, ok := client.IsClubMemberExist(p.ClubId, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是亲友圈创建人或管理员,无权操作"
		b.Response()
		return
	}
	if role != ClubRoleOwner {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是创建人,无权操作"
		b.Response()
		return
	}

	data := map[string]interface{}{
		"club_id":     p.ClubId,
		"game_id":     p.GameId,
		"play_rule":   p.PlayRule,
		"play_option": p.PlayOption,
		"create_time": time.Now().Unix(),
	}

	_, err = client.NewClubFloor(data)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//亲友圈更新了要发送亲友圈所有成员
	client.BroadCastMsgToLobby(p.ClubId, GenBroadcastMsg(ModuleClub, ActionAddFloor, p.ClubId))
	b.ResponseSuccess()
}

// @Title 更新亲友圈的楼层
// @Description 更新亲友圈的楼层
// @Param   id        	body    int     true      "id"
// @Param   club_id  	body    int     true      "俱乐部id,不是俱乐部密码"
// @Param   game_id  	body    int     true      "游戏id"
// @Param   play_rule 	body    string  true      "游戏玩法规则"
// @Param   play_option body    int     true      "游戏玩法选项"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /update-floor [post]
func (b *ClubController) UpdateFloor() {
	type Params struct {
		Id         int64  `json:"id" valid:"Required"`
		ClubId     int64  `json:"club_id" valid:"Required"`
		GameId     int64  `json:"game_id"`
		PlayRule   string `json:"play_rule"`
		PlayOption int64  `json:"play_option"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}

	if !b.ValidParams(&p) {
		return
	}

	ok := client.IsHostAndAdminByFloorId(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是亲友圈创建人或管理员,无权操作"
		b.Response()
		return
	}

	data := map[string]interface{}{
		"game_id":     p.GameId,
		"play_rule":   p.PlayRule,
		"play_option": p.PlayOption,
	}
	_, err := client.UpdateClubFloor(data, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//亲友圈更新了要发送亲友圈所有成员
	client.BroadCastMsgToLobby(p.ClubId, GenBroadcastMsg(ModuleClub, ActionUpdateFloor, p.Id))
	b.ResponseSuccess()
}

// @Title 更新亲友圈的楼层的名字
// @Description 更新亲友圈的楼层的名字
// @Param   id          	body    int     true      "id"
// @Param   club_id  		body    int     true      "俱乐部id,不是俱乐部密码"
// @Param   floor_name  	body    string  true      "楼层名称"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /update-floor-name [post]
func (b *ClubController) UpdateFloorName() {
	type Params struct {
		Id        int64  `json:"id" valid:"Required"`
		ClubId    int64  `json:"club_id" valid:"Required"`
		FloorName string `json:"floor_name"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if p.FloorName != "" {
		b.Valid.MaxSize(p.FloorName, 7, "floor_name").Message("最多为7个字符")
		b.Valid.MinSize(p.FloorName, 2, "floor_name").Message("最少为2个字符")
	}
	if !b.ValidParams(&p) {
		return
	}

	ok := client.IsHostAndAdminByFloorId(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是亲友圈创建人或管理员,无权操作"
		b.Response()
		return
	}

	data := map[string]interface{}{
		"floor_name": p.FloorName,
	}
	_, err := client.UpdateClubFloor(data, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//亲友圈更新了要发送亲友圈所有成员
	client.BroadCastMsgToLobby(p.ClubId, GenBroadcastMsg(ModuleClub, ActionUpdateFloor, p.Id))
	b.ResponseSuccess()
}

// @Title 更新亲友圈的楼层的名字
// @Description 更新亲友圈的楼层的名字
// @Param   id          	body    int     true      "id"
// @Param   club_id  		body    int     true      "俱乐部id,不是俱乐部密码"
// @Param   floor_notice  	body    string  false      "楼层名称"
// @Success 0 {string} 状态码
// @Failure 400
// @Failure 404
// @router /update-floor-notice [post]
func (b *ClubController) UpdateFloorNotice() {
	type Params struct {
		Id          int64  `json:"id" valid:"Required"`
		ClubId      int64  `json:"club_id" valid:"Required"`
		FloorNotice string `json:"floor_notice"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}

	ok := client.IsHostAndAdminByFloorId(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是亲友圈创建人或管理员,无权操作"
		b.Response()
		return
	}

	data := map[string]interface{}{
		"floor_notice": p.FloorNotice,
	}
	_, err := client.UpdateClubFloor(data, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//亲友圈更新了要发送亲友圈所有成员
	client.BroadCastMsgToLobby(p.ClubId, GenBroadcastMsg(ModuleClub, ActionUpdateFloor, p.Id))
	b.ResponseSuccess()
}

// @Title 列出所有楼层
// @Description 列出所有楼层
// @Param   page_size    body   int     true       "每页显示数量"
// @Param   page_index   body   int     true       "第几页"
// @Param   club_id      body   int     false      "亲友圈id"
// @Success 0 {object} []common.ClubMember 亲友圈成员列表
// @router /list-floor [post]
func (b *ClubController) ListFloor() {
	type Params struct {
		ListParams
		ClubId int64 `json:"club_id"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	floor, count, err := client.ListFloor(p.ListParams, p.ClubId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	b.Res.Data = floor
	b.Res.Count = count
	b.ResponseSuccess()
}

// @Title 删除楼层
// @Description 删除楼层
// @Param   id      body   int     true        "楼层id"
// @Param   club_id  		body    int     true      "俱乐部id,不是俱乐部密码"
// @Success 0 {string} 状态码
// @router /delete-floor [post]
func (b *ClubController) DeleteFloor() {
	type Params struct {
		Id     int64 `json:"id" valid:"Required"`
		ClubId int64 `json:"club_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	ok := client.IsHostAndAdminByFloorId(p.Id, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是亲友圈创建人或管理员,无权操作"
		b.Response()
		return
	}

	data := map[string]interface{}{
		"is_delete": 1,
	}
	_, err := client.UpdateClubFloor(data, p.Id)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	client.BroadCastMsgToLobby(p.ClubId, GenBroadcastMsg(ModuleClub, ActionDeleteFloor, p.Id))
	b.ResponseSuccess()
}

// @Title 房主拉玩家加入亲友圈(玩家被动加入)
// @Description 申请加入亲友圈(玩家被动加入)
// @Param   uid     	body   int        true        "玩家id"
// @Param   club_id     body   int        true        "俱乐部id,不是俱乐部密码"
// @Success 0 {string}  状态码
// @router /passive-join-club [post]
func (b *ClubController) PassiveJoinClub() {
	type Params struct {
		Uid    int64 `json:"uid"`
		ClubId int64 `json:"club_id" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if p.Uid == 0 {
		b.ResponseFail("请输入正确的玩家ID")
		return
	}
	_, role, ok := client.IsClubMemberExist(p.ClubId, b.Uid)
	if !ok {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是此亲友圈成员,无权操作"
		b.Response()
		return
	}
	if role != ClubRoleOwner && role != ClubRoleAdmin {
		b.Res.Code = ErrUserForbidden
		b.Res.Msg = "您不是创建人或管理员,无权操作"
		b.Response()
		return
	}

	user, err := client.QueryUserInfoById(p.Uid)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if user.Uid != p.Uid {
		b.ResponseFail("玩家不存在,请检查")
		return
	}

	//查找是否已经是此亲友圈成员(正常或禁言)，如果是无需重复加入
	status, _, ok := client.IsClubMemberExist(p.ClubId, p.Uid)
	if ok {
		if status == ClubMemberNormal || status == ClubMemberMute {
			b.Res.Msg = "玩家已是此亲友圈成员,无需重复加入"
			b.Res.Code = ErrAlreadyExist
			b.Response()
			return
		} else if status == ClubMemberAudit {
			b.Res.Msg = "此玩家已申请加入,请及时等待审核"
			b.Res.Code = ErrAlreadyExist
			b.Response()
			return
		}
	}

	club, err := client.ClubStructById(p.ClubId)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if club.Id == 0 || club.Status == ClubDismiss {
		b.ResponseFail("亲友圈不存在")
		return
	}

	//获取亲友圈人数限制
	rule, err := h5.RuleByType(RuleClubMemberNum)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	if rule.Id != 0 {
		if rule.Amount <= club.Member {
			b.ResponseFail("加入失败,亲友圈成员已达上限")
			return
		}
	} else {
		LogClient.Error("亲友圈成员数限制未设置,请限制")
	}

	cm := map[string]interface{}{
		"uid":         p.Uid,
		"cid":         p.ClubId,
		"role":        ClubRoleNormal,
		"status":      ClubMemberNormal,
		"create_time": time.Now().Unix(),
	}
	_, err = client.NewClubMember(cm)
	if err != nil {
		LogClient.Error(b.DatabaseError(err.Error()))
		return
	}
	//更新亲友圈成员总数
	client.UpdateClubMemberNum(club.Id)
	//添加亲友圈成员到redis里,
	Key := fmt.Sprintf("%v%v", KeyClub, club.Id)
	Redis.HSet(Key, p.Uid, p.Uid)
	u, _ := client.QueryUserInfoById(b.Uid)
	//发邮件通知玩家
	t := time.Now()
	data := map[string]interface{}{
		"type":      EmailTypeSys,
		"suid":      0,
		"nickname":  "系统消息",
		"title":     "亲友圈通知",
		"content":   fmt.Sprintf("亲友圈创建人(ID:%v,昵称:%v)在%v把您拉进了亲友圈(ID:%v)", b.Uid, u.Nickname, t.Format("2006-01-02 15:04"), club.Password),
		"status":    0,
		"send_time": t.Unix(),
	}
	//通知玩家您的已经被亲友圈创建人拉进了亲友圈
	//发送消息给申请者，提示它你已成功加入
	client.SendEmailAndNotifyClient(data, p.Uid, 0, GenBroadcastMsg(ModuleClub, ActionJoinClubSuccess, p.ClubId))
	b.ResponseSuccess()
}

// @Title 改变俱乐部创建人
// @Description 改变俱乐部创建人
// @Param   id             body    int     true      "俱乐部id"
// @Param   password  	   body    int     true      "俱乐部密码,传过来方便后台"
// @Param   new_host  	   body    int     true      "俱乐部新创建人"
// @Success 0 {string} 状态码
// @router /change-club-host [post]
func (b *ClubController) ChangeClubHost() {
	type Params struct {
		Id       int64 `json:"id" valid:"Required"`
		NewHost  int64 `json:"new_host" valid:"Required"`
		Password int64 `json:"password" valid:"Required"`
	}
	var p Params
	if !b.DecodeParams(&p) {
		return
	}
	if !b.ValidParams(&p) {
		return
	}
	err := pc.ChangeClubHost(p.Id, p.NewHost)
	if err != nil {
		LogPc.Error(b.DatabaseError(err.Error()))
		return
	}
	b.ResponseSuccess()
	//亲友圈更改了创建人，发送通知给新创建人
	u, _ := client.QueryUserInfoById(b.Uid)
	//发邮件通知玩家
	t := time.Now()
	data := map[string]interface{}{
		"type":      EmailTypeSys,
		"suid":      0,
		"nickname":  "系统消息",
		"title":     "亲友圈通知",
		"content":   fmt.Sprintf("亲友圈创建人(ID:%v,昵称:%v)在%v把亲友圈(ID:%v)转让给您,请知悉.", b.Uid, u.Nickname, t.Format("2006-01-02 15:04"), p.Password),
		"status":    0,
		"send_time": t.Unix(),
	}
	//通知玩家您的已经被亲友圈创建人拉进了亲友圈
	//发送消息给申请者，提示它你已成功加入
	client.SendEmailAndNotifyClient(data, p.NewHost, 0, GenBroadcastMsg(ModuleClub, ActionChangeHost, p.Id))
}
